<?php
/**
 * 公共函数类
 * ver 1.1
 * author Myxf
 */
class AppManager
{
    private $return = false;

    function __construct(){
    }

    //获取主程序版本信息并升级
    public function mVersion($config,$upgrade){
	    $url = $config['gitee']."/raw/master/library/ver.php";
    	$backdata = $this->vget($url);
    	$backdata = explode(":", $backdata);
    	$config['newVer'] = $backdata[1];
    	$config['newDes'] = $backdata[2];
    	if ($upgrade===1 && !empty($backdata[3])){
        if(ini_get("phar.readonly")!=0){
          $config['upgrade'] = "phar扩展未开启，请配置php.ini，phar.readonly = 0并去掉前面的分号重启";
        }else if(!extension_loaded("openssl")){
          return "php_openssl扩展未开启，请配置php.ini,去掉extension=php_openssl.dll前面的分号重启";
        }else{
          if ($config['newVer']==$config['Version']){
            $config['upgrade'] = "主程序不需要升级";
          }else{
            $config['upgrade'] = $this->mUpgrade($config,$backdata[3]);
          }
          $config['app_upgrade'] = $this->mappUpgrade($config);
        }
    	}
    	return $config;
    }

    //自动升级类
   	private function mUpgrade($config,$file_list){
      $phar = new Phar(__DIR__); 
   		$file_list = explode(",", $file_list);
      //获取主程序文件列表
      $file = scandir("phar://phpfun.phar/");
      foreach ($file as $key => $one) {
        if (substr($one,0,-3)=="php"){
          try {
            $phar->delete($one);
          } catch (Exception $e) {
            return "更新失败";
          }
        }
      }

      foreach ($file_list as $key => $one) {
        try {
          $phar->addFile($config['gitee']."/raw/master/src/".$one, $one);
        } catch (Exception $e) {
            return $appName."下载失败";
        }
      }
      return "主程序升级成功";
   	}

   	//升级已安装的app
   	private function mappUpgrade($config){
      //获取已安装的app列表
      $mapp = $this->mApp($config);
      $mi = 0;
   		foreach ($mapp as $key => $one) {
        if ($one['ClassState']=="已安装" && $one['ClassNewVer']!=$one['Classver']){
          $this->mAppInstall($config,$one['ClassName'],1);
          $mi++;
        }
   		}
      if ($mi==0){
        return "APP不需要更新";
      }else{
        return "APP更新成功";
      }
   	}

   	//安装app
   	public function mAppInstall($config,$appName,$upgrade = 0){
   		$this->return = true;
   		//先检查是否安装
   		$class = $this->mClass($appName);
   		if($class && $upgrade==0){
   			return $appName.",app已安装";
   		}else if(ini_get("phar.readonly")!=0){
    		return "phar扩展未开启，请配置php.ini，phar.readonly = 0并去掉前面的分号重启";
    	}else if(!extension_loaded("openssl")){
    		return "php_openssl扩展未开启，请配置php.ini,去掉extension=php_openssl.dll前面的分号重启";
    	}
      try {
  	    $phar = new Phar(__DIR__);  
  			$phar->addFile($config['gitee']."/raw/master/src/Class/".$appName.".php", "Class/".$appName.'.php');
  			return $appName."app安装成功";
  		} catch (Exception $e) {
      		return $appName."app安装失败";
  		}
   	}

   	//卸载app
   	public function mAppDel($appName){
   		$this->return = true;
   		//先检查是否安装
   		$class = $this->mClass($appName);
   		if(!$class){
   			return $appName.",app未安装";
   		}else if(ini_get("phar.readonly")!=0){
    		return "phar扩展未开启，请配置php.ini，phar.readonly = 0并去掉前面的分号重启";
    	}else if(!extension_loaded("openssl")){
    		return "php_openssl扩展未开启，请配置php.ini,去掉extension=php_openssl.dll前面的分号重启";
    	}
      try {
  	    $phar = new Phar(__DIR__);  
  			$phar->delete("Class/".$appName.'.php');
  			return $appName."app卸载成功";
  		} catch (Exception $e) {
      		return $appName."app卸载失败";
  		}
   	}

   	//检查app安装状态及其版本信息
    public function mApp($config){
     	$this->return = true;
     	$back = array();
     	$url = $config['gitee']."/raw/master/library/APPList.php";
     	$backdata = $this->vget($url);
     	$backdata = explode("\n", $backdata);
     	foreach ($backdata as $key => $one) {
     		$one = explode(":", $one);
     		$back[$one[0]]['ClassName'] = $one[0];
     		$back[$one[0]]['ClassNewVer'] = $one[1];
     		$back[$one[0]]['ClassDes'] = $one[2];
     		$class = $this->mClass($one[0]);
     		$back[$one[0]]['ClassState'] = $class ? "已安装" : "未安装";
     		$back[$one[0]]['Classver'] = $class ? $class->ver : "0";
     	}
     	return $back;
     }

    //载入class类
    public function mClass($ClassName, $args = null) {
        // 检查类名称是否正确，以保证类定义文件载入的安全性
		    if(preg_match('/[^a-z0-9\-_.]/i', $ClassName))exit($ClassName."类名称错误，请检查。");
    		$path = "phar://phpfun.phar/Class/".$ClassName.".php";
    		if (!file_exists($path) && !$this->return)exit($ClassName."类未找到，请检查。");
    		if (!file_exists($path) && $this->return)return false;
    	  require_once $path;
    	  // 检查类定义是否存在
    	  if (!class_exists($ClassName, false))exit($ClassName."类定义不存在，请检查。");
    	  $argString = '';$comma = ''; 
    		if(null != $args)for ($i = 0; $i < count($args); $i ++) { $argString .= $comma . "\$args[$i]"; $comma = ', '; } 
    		eval("\$".$ClassName." = new ".$ClassName."(".$argString.");"); 
    		return $$ClassName;
     }

     //网络请求类
     private function vget($url){
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 1);
        curl_setopt($curl, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
        curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
        curl_setopt($curl, CURLOPT_AUTOREFERER, 1);
        curl_setopt($curl, CURLOPT_TIMEOUT, 30);
        curl_setopt($curl, CURLOPT_HEADER, 0);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        $tmpInfo = curl_exec($curl);
        if (curl_errno($curl)) {
           return 'Error';
        }
        curl_close($curl);
        return $tmpInfo;
    }
}
